import maya.OpenMaya as om
from typing import List, Tuple

def softModificationToWeight() -> List[Tuple[int, float]]:
    """从当前富选择中提取软修改组件的索引和权重。

    该函数从Maya的当前富选择中提取第一个有效选择的组件索引及其权重值。
    仅支持单索引组件（如顶点、控制点）。

    Returns:
        List[Tuple[int, float]]: 包含(组件索引, 权重值)的元组列表。
        如果无有效选择、组件类型不匹配或发生错误，返回空列表。

    Raises:
        该函数不会显式抛出异常，但内部错误会通过Maya的控制台显示。

    Example:
        >>> weights = softModificationToWeight()
        >>> print(weights)
        [(0, 0.5), (1, 1.0)]
    """
    try:
        # 获取当前富选择对象
        # 创建一个 MRichSelection 对象，用于存储 Maya 中的当前富选择信息
        # 富选择是 Maya 中一种可以包含多种选择信息的选择方式
        rich_sel = om.MRichSelection()
        # 调用 MGlobal 类的 getRichSelection 方法，将当前的富选择信息填充到 rich_sel 对象中
        om.MGlobal.getRichSelection(rich_sel)

        # 将富选择转换为可操作的选择列表
        # 创建一个 MRichSelectionList 对象，它用于将富选择信息转换为一个可遍历和操作的列表
        selection_list = om.MRichSelectionList()
        # 调用 rich_sel 对象的 getSelection 方法，把富选择信息提取到 selection_list 中
        rich_sel.getSelection(selection_list)

        # 检查选择列表是否为空
        # 如果选择列表的长度为 0，说明没有有效的选择，直接返回空列表
        if selection_list.length() == 0:
            return []

        # 提取第一个选择项的组件
        # 创建一个 MDagPath 对象，用于存储 DAG（有向无环图）路径信息
        # 在 Maya 中，场景中的对象通过 DAG 结构组织，MDagPath 可以定位到具体的对象
        dag_path = om.MDagPath()
        # 创建一个 MObject 对象，用于存储组件对象
        # 组件可以是顶点、面等场景中的元素
        component = om.MObject()
        # 调用 selection_list 的 getDagPath 方法，从选择列表的第一个选择项（索引为 0）中获取 DAG 路径和组件对象
        # 并分别存储到 dag_path 和 component 中
        selection_list.getDagPath(0, dag_path, component)

        # 检查组件有效性
        # 调用 component 的 isNull 方法检查组件对象是否为空
        # 调用 hasFn 方法检查组件对象是否具有 MFn.kComponent 类型的功能集
        # 如果组件为空或者不具有有效的组件功能集，说明组件无效，返回空列表
        if component.isNull() or not component.hasFn(om.MFn.kComponent):
            return []

        # 验证是否为单索引组件（顶点/控制点等）
        # 调用 hasFn 方法检查组件对象是否具有 MFn.kSingleIndexedComponent 类型的功能集
        # 单索引组件通常指像顶点、控制点这样可以通过单个索引来访问的组件
        if not component.hasFn(om.MFn.kSingleIndexedComponent):
            # 如果不是单索引组件，使用 MGlobal.displayWarning 方法在 Maya 控制台显示警告信息
            om.MGlobal.displayWarning("仅支持单索引组件类型")
            return []

        # 创建索引组件功能集并提取数据
        # 创建一个 MFnSingleIndexedComponent 对象，用于操作单索引组件
        # 将前面获取的组件对象 component 传递给它，以便后续对组件进行操作
        component_fn = om.MFnSingleIndexedComponent(component)
        # 调用 component_fn 的 elementCount 方法获取组件中的元素数量
        element_count = component_fn.elementCount()

        # 使用列表推导式遍历组件的所有元素
        # 对于每个元素，调用 component_fn.element(i) 获取其索引
        # 调用 component_fn.weight(i).influence() 获取其权重值
        # 将索引和权重值组成一个元组，最终将所有元组组成一个列表并返回
        return [
            (component_fn.element(i), component_fn.weight(i).influence())
            for i in range(element_count)
        ]

    except Exception as e:
        # 如果在上述过程中发生异常，使用 MGlobal.displayError 方法在 Maya 控制台显示错误信息
        om.MGlobal.displayError(f"提取软修改权重失败: {str(e)}")
        # 并返回空列表
        return []